{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Sources, Filters, and Modules by example\n",
    "\n",
    "**Prabhu Ramachandran**\n",
    "\n",
    "**Department of Aerospace Engineering, IIT Bombay**\n",
    "<br/>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Overview\n",
    "\n",
    "- Mayavi has many features\n",
    "- Many sources, filters, and modules\n",
    "- Learn these with simple examples\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Overview\n",
    "\n",
    "* Source: produce data\n",
    "\n",
    "* Filter: filters the data producing more data\n",
    "\n",
    "* Module: visualizes the data\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Getting started\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%gui qt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mayavi import mlab\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Sources\n",
    "\n",
    "* Open supported file: *.vtk, *.xml, *.vt,\n",
    "    *.pvt), VRML2 (*.wrl), 3D Studio (*.3ds), PLOT3D\n",
    "    (*.xyz), STL, BYU, RAW, PLY,  PDB,  SLC,  FACET,  OBJ,  AVSUCD\n",
    "    (*.inp),  GAMBIT (*.neu),  Exodus  (*.exii),  PNG,  JPEG,  BMP,\n",
    "    PNM, DCM, DEM, MHA, MHD, MINC, XIMG, TIFF,\n",
    "\n",
    "* `ParametricSurface`\n",
    "* `PointLoad`\n",
    "* `BuiltinImage`\n",
    "* `BuiltinSurface`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "s = mlab.pipeline.surface(\n",
    "    mlab.pipeline.parametric_surface()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.builtin_surface()\n",
    "s = mlab.pipeline.surface(src)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.builtin_image()\n",
    "img = mlab.pipeline.image_actor(src)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Simple Annotation Modules\n",
    "\n",
    "* Axes\n",
    "\n",
    "* Outline\n",
    "\n",
    "* OrientationAxes\n",
    "\n",
    "* Text, Text3D\n",
    "\n",
    "* Labels\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "obj = mlab.test_plot3d()\n",
    "mlab.axes() # Current object\n",
    "mlab.axes(obj) # Specific object\n",
    "mlab.outline()\n",
    "mlab.text3d(-1, -1, -1, 'Hello!')\n",
    "mlab.orientation_axes()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Common Scalar Modules\n",
    "\n",
    "* Surface\n",
    "\n",
    "* IsoSurface\n",
    "\n",
    "* Glyph\n",
    "\n",
    "* ScalarCutPlane\n",
    "\n",
    "Already seen plenty of examples of these!\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Vector visualization Modules\n",
    "\n",
    "* VectorCutplane\n",
    "\n",
    "* Vectors\n",
    "\n",
    "* WarpVectorCutPlane\n",
    "\n",
    "* Streamline\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Demonstration\n",
    "\n",
    "* Load the `fire_ug.vtu`  file\n",
    "\n",
    "* Demo of some interesting modules\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/fire_ug.vtu')\n",
    "vcp = mlab.pipeline.vector_cut_plane(src)\n",
    "vcp.implicit_plane.widget.normal_to_z_axis = True\n",
    "vcp.implicit_plane.widget.enabled = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "wcp = mlab.pipeline.warp_vector_cut_plane(src)\n",
    "wcp.compute_normals = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Data-specific modules\n",
    "\n",
    "* GridPlane\n",
    "\n",
    "* ContourGridPlane\n",
    "\n",
    "* CustomGridPlane\n",
    "\n",
    "* StructuredGridOutline\n",
    "\n",
    "* SliceUnstructuredGrid\n",
    "\n",
    "* ImagePlaneWidget\n",
    "\n",
    "* ImageActor\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Demonstration\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/sgrid.vts')\n",
    "so = mlab.pipeline.structured_grid_outline(src)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gp = mlab.pipeline.grid_plane(src)\n",
    "gp.grid_plane.axis = 'y'\n",
    "gp1 = mlab.pipeline.grid_plane(src)\n",
    "gp1.grid_plane.axis = 'z'\n",
    "cgp = mlab.pipeline.contour_grid_plane(src)\n",
    "cgp.contour.number_of_contours = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Image plane widgets\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sl = slice(-5, 5, 64j)\n",
    "x, y, z = np.mgrid[sl,sl,sl]\n",
    "scalar = np.sin(np.sqrt(x*x*0.5 + y*y + z*z*2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.scalar_field(x, y, z, scalar)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "o = mlab.outline(src)\n",
    "ip = mlab.pipeline.image_plane_widget(src)\n",
    "ip.ipw.slice_index = 32\n",
    "ip.ipw.plane_orientation = 'y_axes'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Slice Unstructured Grid\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/fire_ug.vtu')\n",
    "sug = mlab.pipeline.slice_unstructured_grid(src)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Advanced modules\n",
    "\n",
    "* TensorGlyph\n",
    "\n",
    "* HyperStreamline\n",
    "\n",
    "* Volume: for volume rendering\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.point_load()\n",
    "o = mlab.outline()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tg = mlab.pipeline.tensor_glyph(src)\n",
    "tg.glyph.mask_input_points = True\n",
    "tg.glyph.mask_points.on_ratio = 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Volume rending\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/heart.vti')\n",
    "vol = mlab.pipeline.volume(src)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* Not always needed\n",
    "\n",
    "* Branch the pipeline\n",
    "\n",
    "* Very powerful\n",
    "\n",
    "* Use modules to visualize filtered results\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* CellDerivatives: Computes derivatives from input point scalar and vector\n",
    "  data, produces cell data on the gradients. Used to calcuate the\n",
    "  vorticity approximately.\n",
    "\n",
    "* CellToPointData: Transforms cell attribute data to point data by\n",
    "  averaging the cell data from the cells at the point.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Example\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/fire_ug.vtu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cell_deriv = mlab.pipeline.cell_derivatives(src)\n",
    "cell_deriv.filter.vector_mode = 'compute_vorticity'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cell2pnt = mlab.pipeline.cell_to_point_data(cell_deriv)\n",
    "vcp = mlab.pipeline.vector_cut_plane(cell2pnt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* Contour: generate iso-surfaces on any input dataset.\n",
    "* CutPlane: slice through any dataset.  Provides a 3D widget interface\n",
    "  to position and move the slice interactively.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* DataSetClipper: Clips input data using a 3D widget.\n",
    "\n",
    "* DecimatePro:  Reduces number of triangles in mesh.\n",
    "\n",
    "* Delaunay2D: 2D Delaunay triangulation.\n",
    "\n",
    "* Delaunay3D: 3D Delaunay triangulation.\n",
    "\n",
    "* ElevationFilter:  Generate scalar data from the elevation in a given\n",
    "  direction.\n",
    "\n",
    "* ExtractEdges: Turns edges into lines.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Demo of Delaunay filters\n",
    "\n",
    "Consider a collection of points sampled from a volume (2D or 3D), how do\n",
    "we find contours for this data?\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Some random data.\n",
    "x, y = np.random.random((2, 100))\n",
    "s = x*x + y*y\n",
    "z = np.ones_like(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Demo: solution\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "# Load up the data\n",
    "src = mlab.pipeline.scalar_scatter(x, y, z, s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ug = mlab.pipeline.delaunay2d(src)\n",
    "surf = mlab.pipeline.surface(ug)\n",
    "surf.actor.property.edge_visibility = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## In 3D\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Some random data.\n",
    "x, y, z = np.random.random((3, 1000))\n",
    "s = x*x + y*y + z*z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "# Load up the data\n",
    "src = mlab.pipeline.scalar_scatter(x, y, z, s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ug = mlab.pipeline.delaunay3d(src)\n",
    "surf = mlab.pipeline.iso_surface(ug)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* ExtractGrid: select a portion of, or subsample an input dataset with\n",
    "  implicit topology.\n",
    "\n",
    "* ExtractTensorComponents: extract components from a tensor field.\n",
    "\n",
    "* ExtractUnstructuredGrid: select a part of an unstructured grid.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/fire_ug.vtu')\n",
    "eug = mlab.pipeline.extract_unstructured_grid(src)\n",
    "eug.filter.trait_set(\n",
    "    cell_clipping=True, cell_minimum=100, cell_maximum=500\n",
    ")\n",
    "surf = mlab.pipeline.surface(eug)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* ExtractVectorComponents: select any of the three components of an\n",
    "  input vector data attribute.\n",
    "\n",
    "* ExtractVectorNorm: Computes the norm (Eucliedean) of the input vector\n",
    "  data (with optional scaling between ).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* GaussianSplatter: Splat input point data onto a grid.\n",
    "\n",
    "* GreedyTerrainDecimation: triangulation of image data after simplifying\n",
    "  it.\n",
    "\n",
    "* ImageChangeInformation: change the spacing and origin of an input\n",
    "  ImageData dataset.\n",
    "\n",
    "* ImageDataProbe: probe any dataset using a Structured Points dataset.\n",
    "  Also allows to convert the scalar data to an unsigned short\n",
    "  to facilitate volume visualization.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "x, y, z = np.random.random((3, 1000))\n",
    "s = x*x + y*y + z*z\n",
    "\n",
    "# Load up the data\n",
    "mlab.clf()\n",
    "src = mlab.pipeline.scalar_scatter(x, y, z, s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gs = mlab.pipeline.gaussian_splatter(src)\n",
    "gs.filter.trait_set(radius=0.2, accumulation_mode='sum')\n",
    "scp = mlab.pipeline.scalar_cut_plane(gs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Image data probe\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/fire_ug.vtu')\n",
    "ip = mlab.pipeline.image_data_probe(src)\n",
    "vol = mlab.pipeline.volume(ip)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* MaskPoints: Selectively passes the input points downstream.  This can be\n",
    "  used to subsample the input points.  *Only passes through points.*\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "\n",
    "* PointToCellData: Convert point to cell data.\n",
    "\n",
    "* PolyDataNormals: Computes normals from input data.  Gives meshes a\n",
    "  smoother appearance.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* QuadricDecimation:  Simplifies triangles of a mesh.\n",
    "\n",
    "* SelectOutput: Select one among several of the outputs of a given\n",
    "  input. Useful for a multi-block data source.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* SetActiveAttribute: set the active data attribute (scalars, vectors and\n",
    "  tensors) on a VTK dataset. Useful to compute contours of one scalar on\n",
    "  the contour of another scalar.\n",
    "\n",
    "* Stripper: Create triangle strips and/or poly-lines. Useful for\n",
    "    regularizing broken up surfaces, such as those created by the Tube filter.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/fire_ug.vtu')\n",
    "ctr = mlab.pipeline.contour(src)\n",
    "ctr.filter.contours = [550]\n",
    "surf = mlab.pipeline.surface(ctr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Colors of `u` on contour of `t`\n",
    "\n",
    "- Using `SetActiveAttribute`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "src = mlab.pipeline.open('data/fire_ug.vtu')\n",
    "ctr = mlab.pipeline.contour(src)\n",
    "ctr.filter.contours = [550]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "setaa = mlab.pipeline.set_active_attribute(ctr)\n",
    "setaa.point_scalars_name = 'u'\n",
    "surf = mlab.pipeline.surface(setaa)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* Threshold: Threshold input points on scalar value.\n",
    "\n",
    "* TransformData: linear transformation to input data using a\n",
    "  tvtk.BoxWidget.  This does not work with\n",
    "  ImageData/StructuredPoints/RectilinearGrid.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* TriangleFilter: Converts input polygons and triangle strips to\n",
    "  triangles.  This is useful when you have a downstream filter that only\n",
    "  processes triangles.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "* Tube: Turns lines into tubes.\n",
    "\n",
    "* UserDefined: This filter lets the user define their own filter\n",
    "  dynamically/interactively from VTK filters.\n",
    "\n",
    "* Vorticity: This filter computes the vorticity of an input vector\n",
    "  field.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Filters\n",
    "\n",
    "* WarpScalar: Warps the input data along a particular direction (either\n",
    "  the normals or a specified direction) with a scale specified by the local\n",
    "  scalar value.  Useful for making carpet plots.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "* WarpVector: Warps the input data along a the point vector attribute\n",
    "  scaled as per a scale factor.  Useful for showing flow profiles or\n",
    "  displacements.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "mlab.clf()\n",
    "room = mlab.pipeline.open('data/room_vis.wrl')\n",
    "src = mlab.pipeline.open('data/fire_ug.vtu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "vort = mlab.pipeline.vorticity(src)\n",
    "evn = mlab.pipeline.extract_vector_norm(vort)\n",
    "iso = mlab.pipeline.iso_surface(evn)\n",
    "vortex_lines = mlab.pipeline.streamline(evn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Summary\n",
    "\n",
    "- Plenty of ways to visualize your data\n",
    "- Hopefully you have a good overview\n",
    "- Several examples\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## What next?\n",
    "\n",
    "- Check the documentation: http://docs.enthought.com/mayavi/mayavi/\n",
    "- Look at more examples: https://github.com/enthought/mayavi/tree/master/examples/mayavi\n",
    "- Learn [traits](http://docs.enthought.com/traits/)\n",
    "- Learn [traitsui](http://docs.enthought.com/traitsui/) and make your own UIs\n"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  },
  "livereveal": {
   "controls": true,
   "help": true,
   "scroll": true,
   "slideNumber": true,
   "transition": "none"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
